The Magistracy is a small game I put together last week. It's playable now and a full run takes ~10 minutes so go ahead - I'll wait. In it you play an agent of the Magistracy - the secret police and the intelligence service in a low-fantasy renaissance-ish world.
This is a game that has been banging around in my notebook for the last year or two. The idea is of course larger than the version I built, and rather than this being a 40k inspired Inquisitor game, this happens in a more realistic fantasy setting. The idea was you are a low level inquisitor assigned to this remote sector with your retinue. You must investigate leads and try to tamp down any heresy that pops up across the sector. You have this small crew, trying to keep things together as it all falls apart, and periodically you have to get involved, and run through some interactive fiction interludes to progress the story.
What we've got here isn't quite that. This is what can I plausibly get done in a week from code, to art, to design, to (no) sound. As a result, a lot of things fell away, and this is focused on the core loop of assigning your agents to locations and missions. The game became the Magistracy. You play an administrative goon assigned to a region for the next 300 days, and your objective is ostensibly to not make a mess of things, but who can stop you if that's what you try to do?
So far, so humdrum. The interesting part to me is that so much of what is happening in the world is unknown or unclear. My preferred part of roguelikes is that the game can change hugely depending on which small element is included or excluded on each run. This happens here with the missions and secret factions involved being randomly selected each runthrough. Sometimes you may get no factions, sometimes one, sometimes two.
Layer on to that that the information you do get is always delayed, and often inaccurate. You are not an omniscient presence. The way you interact with the world is through your agents and where they are assigned. Your agents will periodically send reports to you of the current tension in their assigned cities. How good are your agents at gauging that? How much has it changed since they sent that? Can you rely on the random reports that come from the locations where no agent is assigned? How quick do things change? That's the sort of thing I'm playing with.
There is no "goal". You can not fail. But things can go very bad.
On the technical side this is all data driven. I'm trying something new and tried to design the program as a fat struct with the rendering entirely divorced from the actual game loop. The game is a big struct of data that gets processed every tick, the renderer just makes that visible to players. From early on, even before I hooked things up to the renderer, the game was playing in the background. If this were a more serious thing - you can easily see how easy this would be to hook in to automated testing and make sure things are behaving correctly as it expands. Given the tick-based nature of it, you could store full game playthroughs just in terms of the events that happen and when they're scheduled. All that data lives on the main struct already for scheduling/reporting purposes, so everything here is pretty easy.
This also means that there's maybe 3 classes total in this - everything else is typedefs, enums and typed unions. Typed unions in particular are something I've been using a lot since writing more Odin and they are a great fit here. But that said, there is a break in the pure-data model and its where Ceramic comes in.
The classes that do exist live at the boundary of renderer and gameloop. Ceramic is fairly stateful, and quad and text objects are expensive to allocate, so I keep a map of entity ID (every game object has one of these) to a drawable - location image and nameplates, agent portrait and info plates, mission drawable etc. Each render pass looks up the existing object and updates the diff'ed values to the new content rather than rebuilding.
All of the missions and story etc are JSON blobs. They're replaceable and the game just works more or less. As is, these are just dropped straight into the main Haxe file, but its not a huge amount of work to make that selectable so you can drop in different scenarios etc.
The renderer itself uses Ceramic. It's a nice batteries included framework that I'd done a few sketches in before. A really nice benefit is this all works on mobile and web for free, and I have the ability to export native versions if I expand on this. For UI layout I implemented RectCut in Haxe.
I'm glad to have got this out of the system. Man's reach exceeds his grasp as always, but the game is more enjoyable than it seemed at many points through the week. I think the 10 minute runtime is pretty much right for what is there now, and the intuition of the game getting larger means there needs to be some more levers to push/pull, but that's a problem for future me if this goes anywhere else.